查看原文
其他

弹幕君,别挡着我看小姐姐!

Crossin先生 Crossin的编程教室 2020-10-08

某天代码写得老眼昏花,去B站上摸鱼,突然发现奇怪的现象:

哟呵,B站竟然做了视频前景提取,把弹幕藏到画面人物的后面。识别效果还意外地不错呢。

然后又翻了下,发现这是个叫做“智能防挡弹幕”的功能,我只在部分舞蹈区的视频里找到了开关。

我不知道B站是怎么实现的,但我脑中闪过一个想法:能不能用 Python 实现?简单搜索了一下“python 前景提取”,发现 OpenCV GrabCut 提供了这样的功能。

那么剩下的就好办了。

先放最终实现效果(完整代码见文末):

之前我们的“每周一坑”里有讲过怎么在图片上加文字:【解答】用代码给图片配上文字。用这个方法,可以模拟弹幕的效果:

再用 GrabCut,提取出图片上的前景部分。核心代码:

import numpy as npimport cv2 mask = np.zeros(img.shape[:2],np.uint8) bgdModel = np.zeros((1,65),np.float64) fgdModel = np.zeros((1,65),np.float64) rect = (10, 10, img.shape[1]-10, img.shape[0]-10) cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

img 是输入图像,mask 是输出图像,是一个二值化的蒙版(mask),rect 是待检测区域,后面的数字 5 是迭代次数,其他的参数照搬例子即可。输出结果:

有了蒙版之后,就可以对图像进行运算。分别取出带弹幕图像的背景部分,和原图像的前景部分,两个加一起,就是我们最终需要的效果:

核心代码:

img = img * (1-mask)[:,:,np.newaxis] + img * mask[:,:,np.newaxis]

基本功能这样就完成了。将图片的处理方法放到视频中的每一帧,再加上弹幕飞过的效果,就完成了 Python 版的智能防挡弹幕。

更多的一些细节:

1、前景提取的速度比较慢,为了能达到实时效果,我在提取前景时,将图片缩小,获取蒙版之后,再将其放大至原尺寸。蒙版本身的分辨率几乎不影响最终效果,但通过这个方法就可以做到实时。

2、每一帧的处理速度有快有慢,为了稳定帧率,我加入了每帧时间的计算,如果时间不足设定时长,就 sleep 剩下的时间

3、一些过渡帧的识别效果会比较差,导致中间少数蒙版出现类似“跳帧”的效果。为了平滑这些帧,我在程序里记录每一帧蒙版中前景像素的数量,如果当前帧与之前 20 帧的平均值差距超过 50%,那就认为这一帧的前景提取不合格,直接使用之前的蒙版

4、为了模拟实际效果,我还去B站抓了下视频相关的弹幕,它是在一个 xml 文件中:

https://api.bilibili.com/x/v1/dm/list.so?oid=9931722

因为只有一个文件,我就直接通过 SublimeText 的正则替换功能对数据进行了整理,没额外再写爬虫和处理的代码。这是个很实用的小技巧。

代码中我只使用了弹幕内容时间两个值。当到达某条弹幕时间,就把它放入激活列表,添加到图像右侧,随机高度和颜色,然后每一帧将横向位置向左移动。直到图像左侧外部后,从激活列表中移除。

最终效果演示视频:

作为一个 demo,效果勉强可以接受吧。对这种没有预设背景信息,完全靠图像层面计算的话,准确率是不会太高的。所以只有这种背景单一、前景明显的视频效果还不错。而且很明显,白色衣服的效果就不太行。不知道B站的实现方法是怎样,是否有人工干预,是否有预计算。我觉得有的可能性还是很大的,因为毕竟只有少量视频开启了“智能防挡”。如果有了解情况的,欢迎留言。




PS:说来我以前的论文,和这个也算是相关领域。


获取“Python智能防挡弹幕”完整代码,请在公众号(Crossin的编程教室)里回复关键字 弹幕


另外,我们的有奖征稿活动正在进行中,欢迎参与:

编程教室2019新春征稿活动




其他内容回复左侧关键词获取:

python :零基础入门课程目录

新手 :初学者指南及常见问题

资源 :超过500M学习资料网盘地址

项目 :十多个进阶项目代码实例


如需了解视频课程及答疑群等更多服务,请号内回复 码上行动

代码相关问题可以在论坛上发帖提问 bbs.crossincode.com


推荐阅读:

爬抖音 | AI名画 | 押韵工具 | 虎扑 | 如何debug | 查天气 | 我用Python | 知乎 | 排序 | 电影票 | 技术宅 | 单词表 | 新手建议 | 如何提问 中文编程 



欢迎加入

Crossin的编程教室

crossincode.com


  请把我们分享给身边爱学习的小伙伴 :)  

点击文末“阅读原文”,查看更多学习资源


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存